package io.renren.modules.mark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.mark.constant.DatasetConstant;
import io.renren.modules.mark.constant.ItemConstant;
import io.renren.modules.mark.dao.MarkDatasetDao;
import io.renren.modules.mark.dao.MarkTeamUserDao;
import io.renren.modules.mark.entity.MarkDatasetEntity;
import io.renren.modules.mark.entity.MarkItemEntity;
import io.renren.modules.mark.entity.MarkTeamEntity;
import io.renren.modules.mark.service.MarkDatasetService;
import io.renren.modules.mark.service.MarkItemService;
import io.renren.modules.mark.service.MarkTeamService;
import io.renren.modules.mark.utils.MailUtils;
import io.renren.modules.sys.dao.SysUserDao;
import io.renren.modules.sys.dao.SysUserRoleDao;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.entity.SysUserRoleEntity;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;


@Service("markDatasetService")
public class MarkDatasetServiceImpl extends ServiceImpl<MarkDatasetDao, MarkDatasetEntity> implements MarkDatasetService {

    @Autowired
    private MarkTeamService markTeamService;
    @Autowired
    private MarkTeamUserDao markTeamUserDao;
    @Autowired
    private MarkItemService markItemService;
    @Autowired
    private MailUtils mailUtils;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<MarkDatasetEntity> queryWrapper = new QueryWrapper();
        String name = (String) params.get("name");
        String teamId = (String) params.get("teamId");
        Long createUserid = (Long) params.get("createUserid");
        //排序
        params.put("sidx","create_time");
        params.put("order","desc");
        if (StringUtils.isNotEmpty(teamId)) {
            if (!teamId.equals("0")) {
                queryWrapper.eq("team_id", teamId);
            }
        }
        if (StringUtils.isNotEmpty(name)) {
            queryWrapper.like("name", name);
        }
        if(createUserid!=null){
            queryWrapper.eq("create_userid",createUserid);
        }
        IPage<MarkDatasetEntity> page = this.page(
                new Query<MarkDatasetEntity>().getPage(params),
                queryWrapper
        );
        Map<Integer, String> map = new HashMap<Integer, String>();
        List<MarkTeamEntity> list = markTeamService.list();
        for (MarkTeamEntity markTeamEntity : list) {
            map.put(markTeamEntity.getTeamId(), markTeamEntity.getName());
        }
        List<MarkDatasetEntity> records = page.getRecords();
        for (MarkDatasetEntity record : records) {
            record.setTypeName(DatasetConstant.TYPELIST.get(record.getType()));
            record.setTeamName(map.get(record.getTeamId()));
            record.setStateName(DatasetConstant.STATEMAP.get(record.getState()));
            if(record.getState()>0){
                record.setIsSend(true);
            }
            int tolCnt = record.getTotal();
            record.setItemNum(tolCnt);
            if (tolCnt == 0 ) {
                record.setSchedule("0");
            }else {
                int count = record.getProcess();
                BigDecimal bCnt = new BigDecimal(count*100);
                BigDecimal bTolCnt = new BigDecimal(tolCnt);
                BigDecimal rel = bCnt.divide(bTolCnt, 2, RoundingMode.HALF_UP);
                record.setSchedule(rel.toString());
            }

        }
        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void submit(Integer id) {
        MarkDatasetEntity dataset = baseMapper.selectById(id);
        Integer state = dataset.getState();
        String  name = dataset.getName();
        if (state != null) {
            if (state > 0) {
                throw new RRException("任务已分发，不能重新分发");
            } else {
                //查找当前团队下的所有人员
                Integer teamId = dataset.getTeamId();
                if (teamId == null)
                    throw new RRException("任务尚未分配团队");
                List<Integer> userIdlist = markTeamUserDao.selectUserIdlist(teamId);
                if (userIdlist.size()==0) {
                    throw new RRException("团队尚未添加成员或团队不存在");
                }

                //查询被分发的普通成员
                QueryWrapper<SysUserRoleEntity> query = new QueryWrapper<>();
                query.select("DISTINCT user_id");
                query.in("user_id",userIdlist);
                query.eq("role_id",2);
                List<Long> markUserId = sysUserRoleDao.selectList(query).stream().map(u -> u.getUserId()).collect(Collectors.toList());
                if(markUserId.size()==0){
                    throw new RRException("失败，该团队下没有标注员");
                }

                //查询被分发的审批员
                query = new QueryWrapper<>();
                query.select("DISTINCT user_id");
                query.in("user_id",userIdlist);
                query.eq("role_id",1);
                List<Long> approveUserId = sysUserRoleDao.selectList(query).stream().map(u -> u.getUserId()).collect(Collectors.toList());
                if(approveUserId.size()==0){
                    throw new RRException("失败，该团队下没有审批员");
                }

                //查找该任务下的所有图片
                QueryWrapper<MarkItemEntity> queryWrapper = new QueryWrapper<>();
                queryWrapper.select("item_id");
                queryWrapper.eq("dataset_id", id);
                List<MarkItemEntity> itemEntList = markItemService.list(queryWrapper);
                if(itemEntList.size()==0){
                    throw new RRException("当前任务下没有图片");
                }

                //遍历图片，平均分发给人员，并将人员id设置进去
                int flag = 0;
                Set<Long> userIdSet = new HashSet<>(); //分配到任务的人员添加到set集合中
                for (MarkItemEntity emty : itemEntList) {
                    if (flag >= markUserId.size()) flag = 0;
                    Long userId = markUserId.get(flag);
                    emty.setUserId(userId);
                    emty.setState(ItemConstant.ItemType.SEND.getValue());
                    emty.setTeamId(teamId);
                    userIdSet.add(userId);
                    flag++;
                }
                markItemService.updateBatchById(itemEntList);

                //更新任务状态为1
                baseMapper.update(null,
                        new UpdateWrapper<MarkDatasetEntity>().set("state", 1)
                                .set("total",itemEntList.size()).eq("dataset_id", id));

                //给人员发邮件
                QueryWrapper queryWrapper1 = new QueryWrapper();
                queryWrapper1.select("email");
                queryWrapper1.in("user_id",userIdSet);
                List<SysUserEntity> list = sysUserDao.selectList(queryWrapper1);
                List<String> collect = list.stream().map(sysUser -> sysUser.getEmail()).collect(Collectors.toList());
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        mailUtils.sendMails(collect,name);
                    }
                });
                thread.start();
//                try{
//                    mailUtils.sendMails(collect,name);
//                }catch (Exception e){
//                    System.out.println(e.getMessage());
//                    throw new RRException("邮件发送异常");
//                }
            }
        } else {
            throw new RRException("任务状态异常，请联系管理员");
        }
    }

}